using System.Reflection;
using Client.Base;
using Cysharp.Threading.Tasks;
using UnityEngine;

namespace Client.Hotfix
{
    public abstract class BaseUI
    {
        public GameObject UIGameObject { get; private set; }

        private bool processing = false;
        private bool isCreated = false;
        protected UIPrefabAttribute prefabAttribute;
        protected ReferenceCollector rc;
        public bool IsShowed { get; private set; } = false;
        public async UniTask Show()
        {

            if (UIGameObject == null)
            {
                if (processing) return;
                processing = true;
                await Create();
                processing = false;
                if (!isCreated) return;
                OnCreate();
            }
            else
            {
                if (IsShowed) return;
                IsShowed = true;
            }
            OnShow();
            UIGameObject.SetActive(true);
        }

        public void Hide()
        {
            if (UIGameObject == null || !IsShowed) return;
            IsShowed = false;
            OnHide();
            UIGameObject.SetActive(false);
        }

        public void Destroy()
        {
            if (UIGameObject != null)
            {
                GameObject.Destroy(UIGameObject);
                UIGameObject = null;
            }
            OnDestroy();
            isCreated = false;
            processing = false;
            IsShowed = false;
        }

        private async UniTask Create()
        {
            var type = this.GetType();
            var attr = type.GetCustomAttribute(typeof(UIPrefabAttribute), false);
            if (attr == null)
            {
                this.Log($"UIPrefabAttribute not found on {type.FullName}");
                isCreated = false;
                return;
            }

            prefabAttribute = attr as UIPrefabAttribute;
            var dependPrefab = prefabAttribute.dependPrefab;
            UIGameObject = await UGF.Instance.Resolve<ResourceService>().LoadAssetWithInstantiateAsync(dependPrefab);
            rc = UIGameObject.GetComponent<ReferenceCollector>();
            if (UIGameObject == null)
            {
                this.Log($"Failed to instantiate prefab: {dependPrefab}");
                isCreated = false;
                return;
            }
            var parent = UIRoot.Instance.GetLayer(prefabAttribute.layer);
            UIGameObject.transform.SetParent(parent, false);
            UIGameObject.transform.SetAsLastSibling();
            UIGameObject.name = type.Name;
            isCreated = true;
        }

        protected abstract void OnCreate();
        protected virtual void OnShow() { }
        protected virtual void OnHide() { }
        protected virtual void OnDestroy() { }
    }

}
